Getting started with Apama EPL

The correlator is Apama’s core event processing and correlation engine. The interface to the correlator lets you inject events that the correlator analyzes. You can configure the correlator to watch for particular events or patterns of interest. In addition, you specify the actions to undertake when the correlator identifies such patterns. Identification of events of interest plus what to do when such events are found constitute an Apama application’s logic.

To deploy an application on the correlator, you can use the correlator’s native Apama Event Processing Language (EPL).

This part teaches you how to write EPL programs. While some programming experience is assumed, no prior knowledge of EPL is assumed.

Apama EPL is an event-driven programming language. It lets you write applications that:

  • Monitor streams of events to find particular events or patterns of events of interest.
  • Analyze events (or patterns of events) of interest to determine whether some action is appropriate.
  • Perform actions based on particular events or patterns of events.

This section discusses the main concepts you must understand to write applications in EPL.

Apama Plugin for Eclipse provides tutorials that can help you get started with EPL. On the Welcome page of Apama Plugin for Eclipse, click Tutorials under the Apama heading.

Info
MonitorScript is the old name for EPL. You might still see the old name in the product documentation.

Introduction to Apama Event Processing Language

EPL is a flexible and powerful “curly-brace”, domain-specific language designed for writing programs that process events. In EPL, an event is a data object that contains a notification of something that has happened, such as a customer order was shipped, a shipment was delivered, a sensor state change occurred, a stock trade took place, or myriad other things. Each kind of event has a type name and one or more data elements (called fields) associated with it. External events are received by one or more adapters, which receive events from the event source and translate them from a source-specific format into Apama’s internal canonical format. Derived events can be created as needed by EPL programs.

Though it contains many of the familiar constructs and features found in general-purpose programming languages like Python or Java, EPL also has special features to make it easy to aggregate, filter, correlate, transform, act on, and create events in a concise manner. Here is the canonical “Hello world” example written in EPL:

monitor HelloWorld
{
   action onload()
   {
      print "Hello world!";
   }
}

The Apama event processor, called the correlator, receives events of various types from external sources. The EPL programs that process these events are monitors.

Monitors have registered event handlers, called listeners, for events of particular types with specific combinations of data values or ranges of values. When a listener detects an event of interest, it triggers a particular action. If there are no listeners for an event, the correlator either discards it or passes it to a listener specifically for events that have no handler. A monitor instance processes events on one correlator and can send events to communicate with other monitors on the same correlator or remote correlators.

Event handlers in EPL are conceptually similar to methods or functions used for handling user-interface events in other languages, such as Java Swing or SWT applications. In EPL, the correlator executes code only in response to events.

The correlator is capable of looking for hundreds of thousands of different events or different event patterns concurrently. When you write an EPL application, you write a set of monitors and then you inject or load them into a running correlator. As streams of events pass into a correlator, the monitors and their listeners watch for the events or patterns of events that you have specified as being of interest. There are a variety of actions that you can specify that you want the correlator to perform when a listener detects an event or event pattern of interest. For example, the most common action for a monitor is to generate and dispatch a message to an external receiver.

EPL is case-sensitive.

How EPL applications compare to applications in other languages

EPL is an event-oriented programming language, as opposed to an object-oriented language. Because EPL is part of an event-processing framework, it requires a different approach to decomposing the problem you want to solve.

EPL syntax is similar to other scripting languages. EPL has variables, data structures, conditions, and procedures (called actions in EPL). But EPL supports a paradigm that is different from that supported by other scripting languages:

  • A monitor is the basic module in EPL programs.
  • All communication is by means of message passing.
  • All processing is triggered in response to events.
  • Monitors spawn instances of themselves to generate multiple units of execution and/or to initiate parallel processing.

EPL requires a different way of developing applications.

About dynamic compilation in the correlator

EPL is dynamically compiled. You inject (load) EPL source files into a running correlator. The correlator compiles the files into optimized byte-code representations.

The EPL compiler is strict. There is no implicit type conversion. You cannot discard return values. To minimize the chance of runtime errors, your code must be explicit and not make assumptions. The correlator terminates execution of a program at the first runtime error.

The dynamic compilation approach removes the need for a byte code interpreter that supports older versions of byte code. Also, the correlator can apply new optimization techniques during byte code generation.

About the Apama development environment in Apama Plugin for Eclipse

Apama Plugin for Eclipse provides an integrated environment for developing Apama applications. The process of developing an Apama application is centered around an Apama project. In Apama Plugin for Eclipse, you create a project and then you use Apama Plugin for Eclipse to:

  • Add and manage the component files that make up the application.
  • Write the EPL for your application.
  • Specify the connectivity plug-ins that are necessary for the application.
  • Specify the configuration properties necessary for launching the application.
  • Run and monitor the application.
  • Export the initialization information necessary for deploying the application.
  • Export your EPL files to a correlator deployment package (CDP).

See Using Apama with Apama Plugin for Eclipse for detailed information.

In addition to using Apama Plugin for Eclipse to create Apama projects, you can also do this using the apama_project command-line tool. See Creating and managing an Apama project from the command line for more information.

As you add components to your application, Apama Plugin for Eclipse automatically generates the boilerplate EPL code for the application’s standard features and launches the appropriate editor where you add the code to implement the component’s behavior.

A central Apama feature in Apama Plugin for Eclipse is the EPL editor. The EPL editor provides support for writing EPL, for example:

  • Automatic EPL validation
  • Content assistance
  • Auto-completion
  • Hovering over an event declaration displays the event’s type definition
  • Automatic indenting and bracketing
  • A separate panel shows the hierarchy of the EPL that appears in the editor
  • Ability to define templates for frequently-used fragments of EPL

In Apama Plugin for Eclipse, you can examine the EPL files that are part of the Apama demo applications.

See Overview of developing Apama applications for more information.

Terminology

This topic provides a definition of each important EPL term. The definitions are organized into several groups.

Basic modules

EPL Term

Definition

Application

An Apama application consists of one or more collaborating monitors.

Package

A mechanism for qualifying monitor and event names. Monitors and global events in the same package must each have a unique name within the package.

Context

Contexts allow EPL applications to organize work into threads that the correlator can concurrently execute.

Monitor

A monitor is a basic unit of program execution. Monitors have both data and logic. Monitors communicate by sending and receiving events. A monitor is defined in a .mon file. In a monitor, you can create multiple contexts and divide processing among multiple contexts.

Channel

A string name that monitor instances and receivers can subscribe to in order to receive particular events. Adapter and client configurations can specify the channel to deliver events to. In EPL, you can send an event to a specified channel.

Event (type)

An event is a data object. All events have an event type and an ordered set of event fields. An event type might also have zero or more defined event actions that operate on the event fields.

Field

A data element of an event.

Method

A method is a predefined action. A given EPL type has a given set of methods that it supports.

Data types

EPL Term Definition
Data type Usually referred to as simply type. EPL supports the following value types: boolean, decimal, float, integer, and the following reference types: action, Channel, chunk, context, dictionary, event, Exception, listener, location, optional, sequence, StackTraceElement, stream, string. Also, monitor is a very limited pseudo-type.
sequence An EPL type used to hold an ordered set of objects (referenced by position).
dictionary An EPL type used to hold a keyed set of objects (referenced by key).
optional An EPL type used to hold either zero elements or one element.
location An EPL type that represents a rectangular area in a two-dimensional unitless Cartesian coordinate plane.
chunk An EPL type that references an opaque data set, the data items of which are manipulated only in an EPL plug-in.
listener You can assign an event listener or a stream listener to a variable of this type and then subsequently call quit() on the listener to remove the listener from the correlator.
action An EPL type that references an action. Actions in EPL are the equivalent of methods in object-oriented languages. Actions are user-defined methods that you can define in monitor definitions, event type definitions, and custom aggregate function definitions.
context An EPL type that provides a reference to a context. A context lets the correlator concurrently process events.
stream An EPL type that refers to a stream object. Each stream is a conduit through which items flow. A stream transports items of only one type, which can be any Apama type. Streams are internal to a monitor.
Channel An EPL type that contains a string or a context. A contained string is the name of a channel. A contained context lets you send an event to that context. Defined in the com.apama namespace.
Exception Values of Exception type are objects that contain information about runtime errors. Defined in the com.apama namespace.
StackTrace Element A StackTraceElement type value is an object that contains information about one entry in the stack trace.
Monitors
EPL Term Definition
Monitor name Each monitor has a name that can be used to delete the monitor from the correlator.
Monitor definition The set of source statements that define a monitor.
Monitor instance A monitor instance is created whenever a monitor is loaded into the correlator. Subsequent monitor instances are created whenever a monitor instance spawns. As one time, a monitor instance was referred to as a sub-monitor.
Sub-monitor A monitor instance was previously referred to as a sub-monitor.
Events
EPL Term Definition
Event name Every event must identify its event type. Event types are identified by a unique event name. The event name can also be used to remove the event definition from the correlator.
Event definition The set of source statements that define an event type.
Event type All events of a given event type have the same structure. An event type defines the event name, the ordered set of event fields and the set of event actions that can be called on the event fields.
Event field A data element of an event.
Event action An action defined within an event definition. The action can operate only on the fields of the event and any arguments passed into the action call.
Listeners

EPL Term

Definition

Event listener

A construct that monitors the events passed to, or routed within, a correlator context. When the event pattern matches the event pattern specified in an event listener, the correlator invokes the event listener’s code block. In monitors, it is up to you to define event listeners.

on statement

EPL statement that defines an event listener. An on statement specifies an event expression and a listener action.

Stream listener

A construct that continuously watches for items from a stream and invokes the listener code block each time new items are available.

from statement

EPL statement that defines a stream listener. A from statement specifies a source stream, a variable, and a code block. The from statement coassigns each stream output item to the specified variable and executes the statement or block once for each output item.

Listener action

The action, statement or block part of a listener.

Listener handle

It is possible to assign the handle (reference) to a listener to a listener variable. This variable can then be used to quit the listener.

Event template

Specifies an event type and the set of (or set of ranges of) event field values to match.

Event operator

Relational, logical, or temporal operator that applies to an event template and that you specify in an event expression.

Event expression

An expression, constructed using event operators and event templates, that identifies an event or pattern of events to match.

Streams

See also the above definitions for the stream data type, stream listener, and the from statement.

EPL Term Definition
Stream query A stream query is defined in a monitor. A stream query is a query that the correlator applies continuously to one or two streams. The output of a stream query is one continuous stream of derived items.
Stream source template An event template preceded by the all keyword. It uses no other event operators. A stream source template creates a stream that contains events that match the event template.
Stream network Network of stream source templates, streams, stream queries, and stream listeners. Upstream elements feed into downstream elements to generate derived, added-value items.
Activation When the passage of time or the arrival of an item causes a stream network or an element in a stream network to process items.

Defining event types

Conceptually, an event is an occurrence of a particular item of interest at a specific time. Examples of events include:

  • A price of $100 for a share of IBM stock at noon on November 7, 2014
  • Purchase of 1000 shares of IBM stock at $80 per share at 12:01 PM on December 12, 2014
  • RFID tag 123-456-789 was scanned at 10:05 AM at loading dock 3
  • Purchase order 55555 for 10,000 widgets sent to Acme Motor Supply
  • TCP/IP address 123.4.56.789 just accessed server 5
  • Container X was overfilled greater than 0.2 grams more than standard amount

An event usually corresponds to a message of some form. The correlator is designed to take in huge numbers of messages per second, and sift them for the events or patterns of events of interest. When the correlator detects interesting events or patterns it can undertake a variety of actions.

A correlator can receive events in several ways:

  • You use Apama Plugin for Eclipse to send events from a file.
  • From an adapter that receives an event from an external source. Apama adapters translate events from non-Apama format to Apama format.
  • You run the Apama engine_send utility to manually send events into the correlator.
  • A monitor generates an event within the correlator.
  • You can write an application in C, C++, Java, or.NET that uses the Apama client API to send events into the correlator.

The correlator propagates information by sending events.

In EPL, each event is of a specific type. An event type has a name and a particular set of fields. Each field has a name and is one of a selection of types. Every event instance of a given event type has the same set and order of fields. For the correlator to process an event of a specific event type, it needs to have the event type definition for that type. Having the definition for an event type, lets the correlator

  • Operate on the messages of that event type
  • Create optimal indexing structures for finding events of that type that are of interest

An event type definition specifies the event type’s name and the name and type of each of its fields.

See also Specifying named constant values.

Allowable event field types

A field in an event can be any Apama type. See also Types.

Certain field types are valid only within a certain scope and you cannot pass events with such field types outside that scope. The details are as follows:

  • context — When an event contains a context type field, you can send the event to other monitors within the same correlator but you cannot send the event outside the correlator. In other words, you can send or route the event. See Generating events.
  • chunk, listener and stream — An event that contains one or more of these types of fields is valid only within the monitor that creates it. You cannot send, route, or enqueue an event that contains a field of type chunk, listener or stream.

If an event contains a chunk, listener, or stream field you cannot listen for that event.

For more information, see the description of event in the API reference for EPL (ApamaDoc).

Format for defining event types

In EPL, the format for an event type definition is as follows:

event event_type {
   [
   [ wildcard] field_type field_name; |
   constant field_type field_name := literal; |
   action_definition
   ]...
}
Syntax description

Syntax Element

Description

event

This EPL keyword is required. It indicates an event type definition.

event_type

Replace event_type with a name that you choose for this event type. An EPL best practices convention is to specify an initial capital in event type names, and to capitalize subsequent words in the name. For example: StockTick.

{ }

Enclose the field definitions in curly braces.

wildcard

Specify the wildcard keyword in front of a field definition when you are certain that you will never specify that field in the match criteria for this event type. In other words, when the correlator watches for certain events of this type, the value of a wildcard field is always irrelevant. For more details, see Improving performance by ignoring some fields in matching events.

field_type

Replace field_type with the name of a type. If you specify action, sequence, stream or dictionary, you must also specify the type of the action’s argument(s) and return value if there are any, the type of the values in the sequence or stream, or the type of the dictionary’s key as well as the type of the values in the dictionary. For example: dictionary<integer,string>. For more details, see the descriptions of the dictionary and sequence types in the API reference for EPL (ApamaDoc).

field_name

Replace field_name with a name that you choose for this field. An event can have zero or more fields. You might define an event with no fields in a situation where only detection of the event is needed to start some process.

While there is no limit to the number of fields in an event, the correlator can index up to 32 fields per event. This means that the correlator can match on up to 32 fields per event. If an event type has more than 32 fields, you must specify the wildcard keyword for the additional fields. Note that if the type of an event field is location, that field counts as 2. For example, if you have 28 non-location type fields and 2 location fields, then you have reached the limit of 32 indexed fields. If you try to inject an event definition that specifies more than 32 fields and you do not specify the wildcard keyword for additional fields, the correlator rejects the file. You must add the wildcard keywords to be able to inject the file.

constant

Specify the constant keyword in front of a field definition whose type is boolean, decimal, float, integer, or string and whose value never changes.

literal

If you specify the constant keyword, you must assign a literal to that field. The type of the literal must be the same as the field_type you specified for this field.

action_definition

When you specify an action in an event type definition you can call that action on an instance of the event (see Specifying actions in event definitions), unless it is a static action, in which case you can instead call it on the event type itself (see Defining static actions).

Example event type definition

For example, the EPL definition of an event type for simple financial stock price ticks might include the stock’s name and its price:

event StockTick {
   string name;
   float price;
}

To represent a specific instance of an event, use the following form:

event_type (field1_value, field2_value...)

For example, a StockTick event describing Acme’s new price of 55.20 looks like this:

StockTick("ACME", 55.20)

The reading order of fields in an event type definition and in instances of that event type must always match and is always left-to-right and then top-to-bottom. That is, "ACME" is the value of the name field and 55.20 is the value of the price field.

Working with events

After you define an event type, there are built-in methods you can call on it, and there are various ways that you can make that event available to monitors.

You can call a number of methods on any event type. For an overview of these methods, see the description of event in the API reference for EPL (ApamaDoc).

Making event type definitions available to monitors

A monitor must have information about the type definitions of the events that it processes. You can provide this information as follows:

  • Define the event type in a separate file that contains only event definitions. An event type definition file has a .mon extension. It is still an EPL file even though it contains only event type declarations.

    You can define any number of event types in a single file. A common practice is to define the event interface to a service in a file that is separate from the implementation of that service. You might have a single event interface file and multiple implementations of services that process those event types.

  • Define the event type in the monitor. Only instances of that monitor can process events of that type. Also, events of that type cannot be sent into the correlator from outside. When you define an event type inside a monitor it has a fully qualified name. For example:

    monitor Test
    {
       event Example{}
    }
    

    The fully qualified name for the Example event type is Test.Example and the toString() output for the event name is "Test.Example()".

  • After the optional package specification, define the event type at the beginning of an EPL file that also defines monitors. All event type declarations must be before the monitor declarations. After you inject this file into the correlator, the following monitors can process events of that type:

    • All monitors that you define in the same file
    • All monitors that you inject after you inject the file that contains the event definition.

You might have a need for different event type definitions to have the same event type name. In this situation, define each event type in a different package. Then, in your monitor, use one of the following ways to make the appropriate event type definition available. In the monitor:

  • Specify the fully qualified name of the event type, for example:

    com.apamax.test.Status

  • After any package declaration and before any other declarations, specify a using declaration. For example:

    using com.apamax.test.Status;

    In your code, you can then simply refer to the Status event type.

Do not create EPL structures in the com.apama namespace. This namespace is reserved for future Apama features. If you inadvertently create an EPL structure in the com.apama namespace, the correlator might not flag it as an error in this release, but it might flag it as an error in a future release.

See also Name Precedence.

An event type definition must be injected into the correlator before a monitor that processes events of that type. After you inject an event type definition into the correlator, any monitor that you inject after that can process events of that type.

During development, when you use Apama Plugin for Eclipse to launch a project, it ensures that files are injected in the right order. When more than one project requires the same event definition file, do one of the following:

  • In each project, declare an external dependency on the common event definition file. See Specifying dependencies for a single-user project.
  • Create a project that contains the common event definition file. In each project that requires these event definitions, declare a dependency on the project that contains the common event definition file. See Specifying projects.

Channels and input events

Adapters, Apama client applications, and tools such as the engine_send correlator utility send events into the correlator. Each incoming event is associated with a channel either explicitly or implicitly. An event that has a channel explicitly set is delivered on the specified channel. An event that does not have a channel explicitly set is delivered on the default channel. The default channel’s name is the empty string.

An incoming event that is sent on the default channel goes to each public context. In addition, contexts can subscribe to channels of interest (see Subscribing to channels). An incoming event for which a channel is explicitly set goes to each context that is subscribed to its associated channel. If there are no contexts subscribed to the specified channel the event is discarded.

Events sent into the correlator from, for example, clients and adapters, are not normally delivered to external receivers. However, external receivers can specify the com.apama.input channel in their configuration. This is a wildcard for all events coming into the correlator. Also, an external receiver can specify com.apama.input.channel_name to receive correlator input events that are associated with that particular channel.

When two events are sent to different channels there is no ordering guarantee. The only guarantee is that events going from the same source to the same destination on the same channel will be delivered in order. Also, if there is an external connection with, for example, an adapter or client, then the events must use the same connection for them to be delivered in the same order.

All routable event types can be sent to channels, including event types defined in monitors.

An Apama application can use the Universal Messaging message bus to deliver events on specified channels. If a correlator is configured to connect to Universal Messaging, then a channel might have a corresponding Universal Messaging channel.

See Choosing when to use Universal Messaging channels and when to use Apama channels.